refactor(security): 移除 JWT 依赖,简化为 API Key + Bot ID 认证 (#467)#476
Merged
Conversation
hotplex-ai
previously approved these changes
May 22, 2026
Owner
hotplex-ai
left a comment
There was a problem hiding this comment.
PR #476 审查报告 — hotplex-ai 三维度自动审查
裁决: APPROVE (有 WARN 项,附后供参考)
代码质量: PASS
- DRY/SOLID/命名/错误处理/风格均通过
- 净删除 ~2000+ 行,跨语言 JWT 重复代码消除
- WARN:
docs/guides/enterprise/security-hardening.mditems 3&4 语义重复
非功能性: WARN
- 性能: PASS — 移除 JTI sweep goroutine、HKDF、ECDSA 验证,API Key map 查找 O(1)
- 安全: WARN
- 认证模型从 ES256 JWT 降级为明文 API Key,丢失 token 过期/撤销/签名验证/权限粒度
- API Key 比较未使用
subtle.ConstantTimeCompare(map lookup,注释已说明可接受性) - Dev mode 无 Key 配置时静默放行,建议非 localhost 绑定时输出 WARN 日志
- 浏览器 WebSocket init envelope 明文传输 API Key,文档需强调生产环境 WSS
- 无
api_key_strengthchecker 替代已移除的jwt_strengthchecker
- 并发: PASS — 移除 JTI blacklist sync.Map + sweep goroutine,RWMutex copy-on-write 模式正确
集成与防腐: WARN
- 文档: PASS — 40+ 文档全部同步,CHANGELOG 迁移指南完整
- 测试: PASS — JWT 测试正确清理,新认证路径测试充分
- API 兼容性: FAIL(有意为之) — 10+ Breaking Change(config.Load/NewWatcher/NewAuthenticator 签名变更、SDK API 变更),均有迁移指南覆盖
- 依赖: PASS — 仅移除 JWT 相关依赖(Go/Java/TS),无新增
- 变更范围: WARN
QuickStart.java变量名signingKey应改为apiKey- PII 检测列表移除
eyJ...JWT 模式 docs/guides/enterprise/integration-patterns.md伪代码使用不存在的WithTokenAPIsecurity-hardening.md中HOTPLEX_GATEWAY_TOKEN替换语义需确认
合并后建议跟踪
- 添加
api_key_strengthchecker(最小长度/熵检查) - 非 localhost + 无 API Key 时输出 WARN 日志
- 考虑
AuthenticateKey使用subtle.ConstantTimeCompare - 文档强调生产环境必须 WSS
- 修复
QuickStart.java变量命名和 integration-patterns 伪代码
hotplex-ai
requested changes
May 22, 2026
Owner
hotplex-ai
left a comment
There was a problem hiding this comment.
三维度审查报告
代码质量: PASS (8.5/10)
- DRY: JWT 相关代码清理彻底,无孤立引用
- SOLID: 接口简化合理,耦合度降低
- 命名/错误处理/代码风格均符合项目规范
- ~100 文件的删除一致性良好
非功能性(安全+性能+并发): FAIL (安全 5.5/10)
FAIL 项(合并前必须解决):
-
SEC-001 时序攻击风险 —
auth.go:72API Key 验证使用map[string]bool查找,非常量时间。旧代码的subtle.ConstantTimeCompare被移除且未替换。作为唯一认证门禁,应改为遍历 +subtle.ConstantTimeCompare。 -
SEC-003 Bot ID 伪造风险 —
BotIDFromRequest从未签名的X-Bot-IDheader /bot_idquery param 提取 bot ID,客户端可设置任意值绕过多 bot 隔离。建议添加 API Key-to-BotID 绑定验证,或在安全文档中明确声明此信任边界。 -
SEC-002 凭证生命周期 — 移除 JWT 后失去 token 过期/撤销机制,泄露的 API Key 永久有效。建议添加 per-key last-used 追踪 + 可选 TTL。
WARN 项(合并后尽快处理):
- SEC-004:
api_keyquery param 存在日志泄漏风险 - SEC-005:
RequireSecrets()被删除,生产环境可能无 API Key 启动 - SEC-006: Scopes/roles 被移除,所有 key 拥有相同权限
- CONC-004:
resolveUserID在读锁下调用外部 resolver 可能阻塞
集成与防腐: FAIL
security_fix_test.go被删除 —fixAdminToken、writeEnvVar、unsetEnvVar、fixEnvInGit仍被hotplex doctor --fix使用,但失去了所有测试覆盖。需恢复测试。
WARN 项:
docs/security/Env-Whitelist-Strategy.md中HOTPLEX_GATEWAY_TOKEN占位符未更新为实际变量名
总结:重构执行质量高(代码清理彻底),但安全模型从密码学强绑定(ES256 JWT)降级为静态共享密钥后,需补充恒定时间比较和 Bot ID 绑定验证来维持安全水位。
hrygo
pushed a commit
that referenced
this pull request
May 22, 2026
- SEC-001: API Key 验证改用 subtle.ConstantTimeCompare 防止时序攻击 - SEC-003: BotIDFromRequest 添加信任边界文档注释 - CONC-004: AuthenticateRequest 将 resolver 调用移到读锁外 - 恢复 security_fix_test.go 测试覆盖(fixAdminToken/writeEnvVar/unsetEnvVar/fixEnvInGit) - 移除 Env-Whitelist 文档中已废弃的 HOTPLEX_GATEWAY_TOKEN 引用
移除 ES256 JWT 签名认证体系(jwt.go、HKDF 密钥派生、JTI 黑名单), 替换为 X-API-Key + X-Bot-ID 双头认证模型。浏览器 WebSocket 客户端 通过 AEP init envelope 延迟传递认证信息。 Breaking changes: - 删除 JWT 全部代码(internal/security/jwt.go, jwt_test.go) - 删除 config SecretsProvider 管线(LoadOptions, EnvSecretsProvider) - 删除 client SDK token 生成(client/token.go, gen-token, 08_token_generator) - 删除 Java jjwt/bcprov 依赖 - BotIDFromHeader 重命名为 BotIDFromRequest Migration: 设置 HOTPLEX_ADMIN_TOKEN_1 环境变量, WebSocket 客户端通过 init envelope auth.token/auth.bot_id 传递凭证。 124 files changed, +857/-3815 lines
- QuickStart.java: signingKey → apiKey - integration-patterns.md: Go SDK 用 client.APIKey()/client.BotID(), TS SDK 用 apiKey,Python SDK 用 api_key - security-hardening.md: 合并重复的 Bot ID 审计项 (3&4→3)
- SEC-001: API Key 验证改用 subtle.ConstantTimeCompare 防止时序攻击 - SEC-003: BotIDFromRequest 添加信任边界文档注释 - CONC-004: AuthenticateRequest 将 resolver 调用移到读锁外 - 恢复 security_fix_test.go 测试覆盖(fixAdminToken/writeEnvVar/unsetEnvVar/fixEnvInGit) - 移除 Env-Whitelist 文档中已废弃的 HOTPLEX_GATEWAY_TOKEN 引用
4788864 to
42d94c6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #467
Summary
jwt.go、HKDF 密钥派生、JTI 黑名单),替换为X-API-Key+X-Bot-ID双头认证模型config.Load()接口,删除LoadOptions/SecretsProvider管线Breaking Changes
internal/security/jwt.goX-API-Keyheader)client/token.go(token 生成)X-Bot-IDheaderconfig.LoadOptions/SecretsProviderconfig.Load(path)单参数BotIDFromHeaderBotIDFromRequestJwtTokenGenerator+ jjwt/bcprovX-Bot-IDheadergenerate-test-token.tsauth.tokenMigration Guide
HOTPLEX_ADMIN_TOKEN_1环境变量(替代 JWT signing key)X-API-Key+X-Bot-IDheaderauth.token+auth.bot_id传递凭证Stats
124 files changed, +857 / -3,815 lines
Test plan
go test ./... -short全绿mvn compile通过tsc --noEmit通过py_compile通过